package org.example.managere.controller.feibiao;

import org.example.managere.dto.feibiao.AmKnowledgeOperationDto;
import org.example.managere.dto.feibiao.AmKnowledgeBasicDto;
import org.example.managere.entity.feibiao.AmKnowledgeOperation;
import org.example.managere.repository.feibiao.AmKnowledgeOperationRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import jakarta.persistence.criteria.Predicate;
import jakarta.validation.Valid;
import java.util.*;
import java.math.BigDecimal;
import java.util.stream.Collectors;

/**
 * 电机实时运行监测数据表 Controller
 */
@RestController
@RequestMapping("/api/feibiao/knowledge/operation")
public class AmKnowledgeOperationController {

    @Autowired
    private AmKnowledgeOperationRepository operationRepository;
    
    @Autowired
    private org.example.managere.service.feibiao.AmKnowledgeBasicService basicService;

    /**
     * 分页查询
     */
    @GetMapping
    public Page<AmKnowledgeOperation> list(@RequestParam(defaultValue = "0") int page,
                                           @RequestParam(defaultValue = "10") int size,
                                           @RequestParam(defaultValue = "id,asc") String sort) {
        String[] sortArr = sort.split(",");
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.fromString(sortArr[1]), sortArr[0]));
        return operationRepository.findAll(pageable);
    }

    /**
     * 条件搜索（支持motorId、采集时间区间）
     */
    @GetMapping("/search")
    public Page<AmKnowledgeOperation> search(@RequestParam(required = false) String motorId,
                                             @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") Date startTime,
                                             @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") Date endTime,
                                             @RequestParam(defaultValue = "0") int page,
                                             @RequestParam(defaultValue = "10") int size,
                                             @RequestParam(defaultValue = "id,asc") String sort) {
        String[] sortArr = sort.split(",");
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.fromString(sortArr[1]), sortArr[0]));
        Specification<AmKnowledgeOperation> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (motorId != null && !motorId.isEmpty()) {
                predicates.add(cb.equal(root.get("motorId"), motorId));
            }
            if (startTime != null) {
                predicates.add(cb.greaterThanOrEqualTo(root.get("collectionTime"), startTime));
            }
            if (endTime != null) {
                predicates.add(cb.lessThanOrEqualTo(root.get("collectionTime"), endTime));
            }
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        return operationRepository.findAll(spec, pageable);
    }

    /**
     * 新增
     */
    @PostMapping
    public AmKnowledgeOperation create(@Valid @RequestBody AmKnowledgeOperationDto dto) {
        AmKnowledgeOperation entity = new AmKnowledgeOperation();
        BeanUtils.copyProperties(dto, entity);
        return operationRepository.save(entity);
    }

    /**
     * 更新
     */
    @PutMapping("/{id}")
    public AmKnowledgeOperation update(@PathVariable Integer id, @Valid @RequestBody AmKnowledgeOperationDto dto) {
        Optional<AmKnowledgeOperation> optional = operationRepository.findById(id);
        if (!optional.isPresent()) {
            throw new RuntimeException("记录不存在");
        }
        AmKnowledgeOperation entity = optional.get();
        BeanUtils.copyProperties(dto, entity, "id");
        return operationRepository.save(entity);
    }

    /**
     * 详情
     */
    @GetMapping("/{id}")
    public AmKnowledgeOperation detail(@PathVariable Integer id) {
        return operationRepository.findById(id).orElseThrow(() -> new RuntimeException("记录不存在"));
    }

    /**
     * 删除
     */
    @DeleteMapping("/{id}")
    public void delete(@PathVariable Integer id) {
        operationRepository.deleteById(id);
    }
    
    /**
     * 获取所有可用的电机列表
     */
    @GetMapping("/motors")
    public ResponseEntity<List<AmKnowledgeBasicDto>> getAllMotors() {
        List<AmKnowledgeBasicDto> motors = basicService.findAll();
        return ResponseEntity.ok(motors);
    }
    
    /**
     * 查询单个电机的运行状态统计信息
     */
    @GetMapping("/statistics/{motorId}")
    public ResponseEntity<Map<String, Object>> getOperationStatistics(@PathVariable String motorId) {
        // 获取指定电机的运行数据
        List<AmKnowledgeOperation> operations = operationRepository.findByMotorIdOrderByCollectionTimeDesc(motorId);
        
        Map<String, Object> statistics = new HashMap<>();
        statistics.put("totalRecords", operations.size());
        
        if (!operations.isEmpty()) {
            // 获取最新一条记录
            AmKnowledgeOperation latest = operations.get(0);
            statistics.put("latestCollectionTime", latest.getCollectionTime());
            statistics.put("latestVoltage", latest.getActualVoltage());
            statistics.put("latestCurrent", latest.getActualCurrent());
            statistics.put("latestTemperature", latest.getOperatingTemperature());
            statistics.put("latestSpeed", latest.getRotationSpeed());
            
            // 计算平均值
            OptionalDouble avgVoltage = operations.stream()
                .map(op -> op.getActualVoltage().doubleValue())
                .mapToDouble(Double::doubleValue)
                .average();
            
            OptionalDouble avgCurrent = operations.stream()
                .map(op -> op.getActualCurrent().doubleValue())
                .mapToDouble(Double::doubleValue)
                .average();
                
            OptionalDouble avgTemperature = operations.stream()
                .map(op -> op.getOperatingTemperature().doubleValue())
                .mapToDouble(Double::doubleValue)
                .average();
                
            OptionalDouble avgSpeed = operations.stream()
                .map(op -> op.getRotationSpeed().doubleValue())
                .mapToDouble(Double::doubleValue)
                .average();
                
            statistics.put("averageVoltage", avgVoltage.isPresent() ? avgVoltage.getAsDouble() : 0);
            statistics.put("averageCurrent", avgCurrent.isPresent() ? avgCurrent.getAsDouble() : 0);
            statistics.put("averageTemperature", avgTemperature.isPresent() ? avgTemperature.getAsDouble() : 0);
            statistics.put("averageSpeed", avgSpeed.isPresent() ? avgSpeed.getAsDouble() : 0);
        }
        
        return ResponseEntity.ok(statistics);
    }
} 